package com.salon.client.widgets.panels;

import java.util.Date;
import java.util.List;

import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.util.IconHelper;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.form.LabelField;
import com.extjs.gxt.ui.client.widget.form.NumberField;
import com.extjs.gxt.ui.client.widget.layout.FormLayout;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DecoratedTabPanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;
import com.salon.client.GreetingServiceAsync;
import com.salon.client.Salon;
import com.salon.client.beans.ClientBean;
import com.salon.client.beans.MasterBean;
import com.salon.client.beans.MaterialBean;
import com.salon.client.beans.PriceBean;
import com.salon.client.beans.ProcedureBean;
import com.salon.client.tabItems.IncomeTabItemPanel;
import com.salon.client.tabItems.PriceTabItemPanel;
import com.salon.client.tabItems.ProcedureTabItemPanel;
import com.salon.client.tabItems.SchedulerTabItemPanel;
import com.salon.client.widgets.ClientDialog;
import com.salon.client.widgets.MaterialDialog;
import com.salon.client.widgets.ProcedureDialog;
import com.salon.client.widgets.suggest.ClientSuggest;
import com.salon.client.widgets.suggest.MaterialSuggest;
import com.salon.client.widgets.suggest.ParentSuggestion;
import com.salon.client.widgets.suggest.PriceSuggest;

public class ProcedurePanel extends PopupPanel {
	private DecoratedTabPanel tab = new DecoratedTabPanel();
	private SchedulerTabItemPanel parentPanel = null;
	
	private MasterBean master = null;
	private ClientBean clientBean = null;
	private Date date = null;
	private ProcedureBean procedure = null;
	
	// tabs
	private FlexTable root = new FlexTable();
	private TabPanel tabs = new TabPanel();
	private FlexTable info = new FlexTable();
	private FlexTable mat = new FlexTable();
	
	//fields
	private SuggestBox price = null;
	private SuggestBox client = null;
	protected NumberField cost = new NumberField();
	protected NumberField percentSalary = new NumberField();
	protected NumberField percentCost = new NumberField();
	private ListBox status = new ListBox();
	private PriceProcedurePanel matPanel = new PriceProcedurePanel();
	
	private PriceBean selectedPrice = null;
	public ProcedurePanel(SchedulerTabItemPanel parentPanel) {
		this.parentPanel = parentPanel;
		this.master = master;
		this.date = date;
		setAnimationEnabled(true);
		
		root.setCellSpacing(4);
		root.setStylePrimaryName("brit-main-view");
		FlexCellFormatter rootFormatter = root.getFlexCellFormatter();
		setHeading("<h3><font color=darkgreen>Процедура</font></h3>");
		rootFormatter.setHorizontalAlignment(0, 0, HasHorizontalAlignment.ALIGN_CENTER);
		
		info.setCellSpacing(4);
		info.setStylePrimaryName("brit-main-view");
		tabs.add(info, "Основное");
		
		mat.setWidget(0, 0, matPanel);
		tabs.add(mat, "Материалы");
		tabs.addSelectionHandler(new SelectionHandler<Integer>(){

			@Override
			public void onSelection(SelectionEvent<Integer> event) {
				ProcedurePanel.this.center();
			}
			
		});
		
		int row = -1;
		LabelField lbl = new LabelField("Услуга:");
		lbl.setWidth("150px");
		info.setWidget(++row, 0, lbl);
		info.getFlexCellFormatter().setWidth(row, 0, "150px");
		info.getFlexCellFormatter().setHorizontalAlignment(row, 0, 
				HasHorizontalAlignment.ALIGN_RIGHT);
		
		info.setWidget(row, 1, createPriceField());
		info.getFlexCellFormatter().setWidth(row, 1, "90%");
		info.getFlexCellFormatter().setHorizontalAlignment(row, 1, 
				HasHorizontalAlignment.ALIGN_LEFT);
		
		lbl = new LabelField("Клиент:");
		lbl.setWidth("150px");
		info.setWidget(++row, 0, lbl);
		info.getFlexCellFormatter().setWidth(row, 0, "150px");
		info.getFlexCellFormatter().setHorizontalAlignment(row, 0, 
				HasHorizontalAlignment.ALIGN_RIGHT);
		
		info.setWidget(row, 1, createClientField());
		info.getFlexCellFormatter().setWidth(row, 1, "90%");
		info.getFlexCellFormatter().setHorizontalAlignment(row, 1, 
				HasHorizontalAlignment.ALIGN_LEFT);
		
		lbl = new LabelField("Стоимость:");
		lbl.setWidth("150px");
		info.setWidget(++row, 0, lbl);
		info.getFlexCellFormatter().setWidth(row, 0, "150px");
		info.getFlexCellFormatter().setHorizontalAlignment(row, 0, 
				HasHorizontalAlignment.ALIGN_RIGHT);
		cost.setWidth("100%");
		info.setWidget(row, 1, cost);
		info.getFlexCellFormatter().setWidth(row, 1, "90%");
		info.getFlexCellFormatter().setHorizontalAlignment(row, 1, 
				HasHorizontalAlignment.ALIGN_LEFT);
		
		
		lbl = new LabelField("Скидка клиенту:");
		lbl.setWidth("150px");
		info.setWidget(++row, 0, lbl);
		info.getFlexCellFormatter().setWidth(row, 0, "150px");
		info.getFlexCellFormatter().setHorizontalAlignment(row, 0, 
				HasHorizontalAlignment.ALIGN_RIGHT);
		percentCost.setWidth("100%");
		info.setWidget(row, 1, percentCost);
		info.getFlexCellFormatter().setWidth(row, 1, "90%");
		info.getFlexCellFormatter().setHorizontalAlignment(row, 1, 
				HasHorizontalAlignment.ALIGN_LEFT);
		
		lbl = new LabelField("Процент мастеру:");
		lbl.setWidth("150px");
		info.setWidget(++row, 0, lbl);
		info.getFlexCellFormatter().setWidth(row, 0, "150px");
		info.getFlexCellFormatter().setHorizontalAlignment(row, 0, 
				HasHorizontalAlignment.ALIGN_RIGHT);
		percentSalary.setWidth("100%");
		info.setWidget(row, 1, percentSalary);
		info.getFlexCellFormatter().setWidth(row, 1, "90%");
		info.getFlexCellFormatter().setHorizontalAlignment(row, 1, 
				HasHorizontalAlignment.ALIGN_LEFT);
		
		lbl = new LabelField("Статус:");
		lbl.setWidth("150px");
		info.setWidget(++row, 0, lbl);
		info.getFlexCellFormatter().setWidth(row, 0, "150px");
		info.getFlexCellFormatter().setHorizontalAlignment(row, 0, 
				HasHorizontalAlignment.ALIGN_RIGHT);
		
		status.addItem("Выполнено");
		status.addItem("Запланировано");
		status.setWidth("100%");
		info.setWidget(row, 1, status);
		info.getFlexCellFormatter().setWidth(row, 1, "90%");
		info.getFlexCellFormatter().setHorizontalAlignment(row, 1, 
				HasHorizontalAlignment.ALIGN_LEFT);
		
		
		
		root.setWidget(1, 0, tabs);
		
		HorizontalPanel buttonPanel = new HorizontalPanel();
		buttonPanel.setSpacing(5);
		
		buttonPanel.add(new Button("Сохранить", new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				if (procedure == null) {
					procedure = new ProcedureBean();
				}
				if (!getValue()) {
					return;
				}
				
				if (isAdd) {
					((GreetingServiceAsync) Registry.get(Salon.SERVICE)).
					addProcedure(procedure, new AsyncCallback<ProcedureBean>() {

						@Override
						public void onFailure(Throwable caught) {
							Info.display("Не удалось", "Добавить процедуру");
							
						}

						@Override
						public void onSuccess(ProcedureBean result) {
							Info.display("Добавление процедуры", "Успешно");
							hide();
							if (ProcedurePanel.this.parentPanel != null)
								ProcedurePanel.this.parentPanel.reInitSchedulerTable();
						}
						
					});
				}
				else {
					((GreetingServiceAsync) Registry.get(Salon.SERVICE)).
					updateProcedure(procedure, new AsyncCallback<Void>() {

						@Override
						public void onFailure(Throwable caught) {
							Info.display("Не удалось", "изменить процедуру");
							
						}

						@Override
						public void onSuccess(Void result) {
							Info.display("Изменение процедуры", "Успешно");
							hide();
							if (ProcedurePanel.this.parentPanel != null)
								ProcedurePanel.this.parentPanel.reInitSchedulerTable();
						}
						
					});
				}
				
				
			}
			
		}));
		
		buttonPanel.add(new Button("Расчет", new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				recalcCost();
			}
			
		}));
		
		buttonPanel.add(new Button("Отменить", new ClickHandler() {
			public void onClick(ClickEvent event) {
				hide();
			}}));
		
		buttonPanel.add(new Button("Удалить", new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (isAdd) {
					return;
				}
				((GreetingServiceAsync) Registry.get(Salon.SERVICE)).
				deleteItem("procedures", procedure.getId(), new AsyncCallback<Void>() {

					@Override
					public void onFailure(Throwable caught) {
						Info.display("Не удалось", "удалить процедуру");
						
					}

					@Override
					public void onSuccess(Void result) {
						Info.display("Удаление процедуры", "Успешно");
						hide();
						if (ProcedurePanel.this.parentPanel != null)
							ProcedurePanel.this.parentPanel.reInitSchedulerTable();
					}
					
				});
			}}));
		
		root.setWidget(2, 0, buttonPanel);
	    rootFormatter.setHorizontalAlignment(2, 0, HasHorizontalAlignment.ALIGN_CENTER);
		
		setWidget(root);		
	}
	
	private boolean isAdd;
	public void setData(ProcedureBean procedure, MasterBean master, Date date) {
		tabs.selectTab(0);
		matPanel.setParent(this);
		
		this.procedure = procedure;
		this.master = master;
		this.date = date;
		
		if (procedure != null) {
			isAdd = false;
			clearAll();
			setValue();
			matPanel.setPrice(procedure.getPrice());
		}
		else {
			isAdd = true;
			clearAll();
			percentSalary.setValue(master.getPercent());
			matPanel.setPrice(null);
		}
		center();
	}
	
	private void clearAll() {
		client.setValue(null);
		client.getTextBox().setEnabled(true);
		clientBean = null;
		
		cost.setValue(null);
		percentCost.setValue(null);
		percentSalary.setValue(null);
		status.setSelectedIndex(0);
		
		price.setValue(null);
		price.getTextBox().setEnabled(true);
		
		cost.setValue(null);
	}
	
	private void addPrice(PriceBean bean) {
		matPanel.addPrice(bean.clonePrice());
	}
	
	private void setValue() {
		if (procedure != null) {
			cost.setValue(procedure.getCost());
			
			percentSalary.setValue(procedure.getPercent());
			percentCost.setValue(procedure.getDiscount());
			status.setSelectedIndex(procedure.getStatus() ? 0 : 1);
			
			//clientBean = procedure.getClient();
			//if (clientBean != null) {
			if (procedure.getClientName() != null) {
				client.setValue(procedure.getClientName());
				client.getTextBox().setEnabled(false);
				
				if (clientBean == null) {
					clientBean = new ClientBean();
					clientBean.setId(procedure.getClientId());
				}
			}


			//}
			
		}
	}
	
	private boolean getValue() {
		procedure.setStatus(status.getSelectedIndex() == 0);
		if (procedure == null) {
			return false;
		}
		List<PriceBean> price = matPanel.getPrice();
		if (((price == null || (price.size() == 0))) && procedure.getStatus() == true) {
			Info.display("Выберите", "услугу");
			return false;
		}
		procedure.setClient(clientBean);
		procedure.setMasterId(master.getId());
		procedure.setDate(date);
		
		recalcCost();
		procedure.setCost(cost.getValue().intValue());
		if (percentCost.getValue() != null)
			procedure.setDiscount(percentCost.getValue().intValue());
		if (percentSalary.getValue() != null)
		procedure.setPercent(percentSalary.getValue().intValue());
		
		procedure.setPrice(matPanel.getPrice());
		return true;
	}
	
	public void recalcCost() {
		List<PriceBean> prices = matPanel.getPrice();
		float res = 0;
		for (PriceBean bean : prices) {
			res += bean.getCost();
		}
		
		float percent = 0;
		if (percentCost.getValue() != null) {
			percent = percentCost.getValue().intValue();
		}
		
		res = res - res * (percent/100);
		
		cost.setValue(new Float(res).intValue());
	}
	
	protected void setHeading(String string) {
		root.setHTML(0, 0, string);
	}
	
	private FlexTable createPriceField() {
		price = new SuggestBox(new PriceSuggest());
		price.setFocus(true);
		price.setWidth("270px");
		
		price.setLimit(MaterialSuggest.MAXSUGGESTIONS);
		price.setAutoSelectEnabled(true);
		SelectionHandler<Suggestion> sel = new SelectionHandler<Suggestion>() {
			public void onSelection(SelectionEvent<Suggestion> event) {
				selectedPrice = (PriceBean)((ParentSuggestion)event.getSelectedItem()).getBean();
				price.setValue(selectedPrice.getName());
				price.getTextBox().setEnabled(false);
			}};
		price.addSelectionHandler(sel);
		PushButton btnClearLName = new PushButton(new Image("salon/icons/glyphlab/prevseries.png"),
			new ClickHandler() {
				public void onClick(ClickEvent event) {
					price.setValue(null);
					price.getTextBox().setEnabled(true);
					price.setFocus(true);
					selectedPrice = null;
			}});
		
		btnClearLName.setStylePrimaryName("brit-transparent");
		btnClearLName.setTitle("Очистить");
		btnClearLName.setSize("16px", "16px");
		
		PushButton addMaterial = new PushButton(new Image("salon/icons/glyphlab/add.gif"),
			new ClickHandler() {
				public void onClick(ClickEvent event) {
					if (selectedPrice != null) {
						addPrice(selectedPrice);
						recalcCost();
						Info.display("Услуга", "добавлена");
					}
					else {
						Info.display("Выберите", "услугу");
					}
					
			}});
			
		addMaterial.setStylePrimaryName("brit-transparent");
		addMaterial.setTitle("Добавить материал");
		addMaterial.setSize("16px", "16px");
		
		FlexTable ftLName = new FlexTable();
		ftLName.setWidget(0, 0, price);
		ftLName.getFlexCellFormatter().setWidth(0, 0, "100%");
		ftLName.setWidget(0, 1, btnClearLName);
		ftLName.getFlexCellFormatter().setWidth(0, 1, "20px");
		ftLName.setWidget(0, 2, addMaterial);
		ftLName.getFlexCellFormatter().setWidth(0, 2, "20px");
		ftLName.setWidth(270 + "px");
		return ftLName;
	}
	
	private FlexTable createClientField() {
		client = new SuggestBox(new ClientSuggest());
		client.setFocus(true);
		client.setWidth("270px");
		
		client.setLimit(MaterialSuggest.MAXSUGGESTIONS);
		client.setAutoSelectEnabled(true);
		SelectionHandler<Suggestion> sel = new SelectionHandler<Suggestion>() {
			public void onSelection(SelectionEvent<Suggestion> event) {
				clientBean = (ClientBean)((ParentSuggestion)event.getSelectedItem()).getBean();
				client.setValue(clientBean.getNiceName());
				percentCost.setValue(clientBean.getDiscount());
				client.getTextBox().setEnabled(false);
				
			}};
		client.addSelectionHandler(sel);
		PushButton btnClearLName = new PushButton(new Image("salon/icons/glyphlab/prevseries.png"),
			new ClickHandler() {
				public void onClick(ClickEvent event) {
					client.setValue(null);
					client.getTextBox().setEnabled(true);
					client.setFocus(true);
					clientBean = null;
			}});
		
		btnClearLName.setStylePrimaryName("brit-transparent");
		btnClearLName.setTitle("Очистить");
		btnClearLName.setSize("16px", "16px");
		
		PushButton addMaterial = new PushButton(new Image("salon/icons/glyphlab/add.gif"),
			new ClickHandler() {
				public void onClick(ClickEvent event) {
					ClientDialog dlg = new ClientDialog(null, null);
					dlg.show();
			}});
			
		addMaterial.setStylePrimaryName("brit-transparent");
		addMaterial.setTitle("Добавить клиента");
		addMaterial.setSize("16px", "16px");
		
		FlexTable ftLName = new FlexTable();
		ftLName.setWidget(0, 0, client);
		ftLName.getFlexCellFormatter().setWidth(0, 0, "100%");
		ftLName.setWidget(0, 1, btnClearLName);
		ftLName.getFlexCellFormatter().setWidth(0, 1, "20px");
		ftLName.setWidget(0, 2, addMaterial);
		ftLName.getFlexCellFormatter().setWidth(0, 2, "20px");
		ftLName.setWidth(270 + "px");
		return ftLName;
	}
}
